package com.totoro.rabbitmq.consumer.queue;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.impl.AMQImpl;
import com.totoro.rabbitmq.RabbitMQProperties;
import com.totoro.rabbitmq.msg.Student;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;

/**
 * 这个类主要监听的是hello队列
 * 采用的还是通过自己创建exchange，queue，以及他们的绑定关系Binding的形式来关联Exchange和Queue。
 */
@Component
@RabbitListener(containerFactory = "simpleRabbitListenerContainerFactory" , queues = RabbitMQProperties.queue.QUEUE)
public class HelloListener {

    @Bean(name = RabbitMQProperties.queue.QUEUE)
    public Queue helloQueue(){
        return new Queue(RabbitMQProperties.queue.QUEUE) ;
    }

    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange(RabbitMQProperties.exchange.EXCHANGE_FANOUT_AMQ) ;
    }

    @Bean
    public Binding fanout_hello_binding(FanoutExchange fanoutExchange, @Qualifier(RabbitMQProperties.queue.QUEUE) Queue helloQueue){
        return BindingBuilder.bind(helloQueue).to(fanoutExchange) ;
    }

    @Bean
    public DirectExchange directExchange(){
        return new DirectExchange(RabbitMQProperties.exchange.EXCHANGE_DIRECT_AMQ) ;
    }

    @Bean
    public Binding direct_hello_binding(DirectExchange directExchange, @Qualifier(RabbitMQProperties.queue.QUEUE) Queue helloQueue){
        return BindingBuilder.bind(helloQueue).to(directExchange).with("exchange_direct_hello") ;

    }
    @RabbitHandler
    public void process(@Payload String msg, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) {
        System.out.println("hello queue msg : " + msg);

        try {
            //手动确认消息
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //拒绝消息
//        try {
//            channel.basicNack(deliveryTag, false, true); // 第三个参数为true，标识拒绝后是否放入队列。导致该方法一直被调用（没有发消息）
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

//        QueueingConsumer consumer = new QueueingConsumer(channel) ;
//        try {
//            channel.basicConsume(RabbitMQProperties.queue.QUEUE, false, consumer) ;
//            while (true) {
//                QueueingConsumer.Delivery delivery = consumer.nextDelivery() ;
//
//                String msg2 = new String(delivery.getBody());
//
//                System.out.println("recieve " + msg);
//                //显示发送ack，只有在前面进行启用显示发送ack机制后才奏效。 false代表是否multiple
//                long tag = delivery.getEnvelope().getDeliveryTag() ;
//                channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    @RabbitHandler
    public void handlerStudent(Student student, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel){
        System.out.println("hello queue student msg is "+ student.getName());
        try {
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
